home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / cross / devpic.lha / devpic / source / picasm / symtab.c < prev    next >
C/C++ Source or Header  |  2000-02-27  |  4KB  |  202 lines

  1. /*
  2.  * picasm -- symtab.c
  3.  *
  4.  * symbol table handling
  5.  *
  6.  * Timo Rossi <trossi@iki.fi>
  7.  * 
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #include "picasm.h"
  15.  
  16. #define HASH_TABLE_SIZE 127
  17.  
  18. typedef struct symbol *symtable[HASH_TABLE_SIZE];
  19.  
  20. /* structure for list of local symbol tables */
  21. struct localtab {
  22.   struct localtab *next;
  23.   struct patch *patch_list;
  24.   symtable table;
  25. };
  26.  
  27. static symtable global_symbol_table;
  28. static struct localtab *local_table_list;
  29.  
  30. /*
  31.  * Compute a hash value from a string
  32.  */
  33. static unsigned int
  34. hash(char *str)
  35. {
  36.   unsigned int h, a;
  37.  
  38.   h = 0;
  39.   while((a = *str++) != '\0') {
  40.     h = 17*h + a;
  41.   }
  42.   return h % HASH_TABLE_SIZE;
  43. }
  44.  
  45. /*
  46.  * Initialize global and local symbol tables
  47.  */
  48. void
  49. init_symtab(void)
  50. {
  51.   struct symbol **sym;
  52.   int n;
  53.  
  54.   for(sym = global_symbol_table, n = HASH_TABLE_SIZE;
  55.       n-- > 0; *sym++ = NULL)
  56.     ;
  57.  
  58.   local_table_list = NULL;
  59. }
  60.  
  61. /*
  62.  * Add a new local symbol table
  63.  */
  64. void add_local_symtab(void)
  65. {
  66.   struct localtab *tab;
  67.   struct symbol **symp;
  68.   int n;
  69.  
  70.   tab = mem_alloc(sizeof(struct localtab));
  71.  
  72.   for(symp = &tab->table[0], n = HASH_TABLE_SIZE;
  73.       n-- > 0; *symp++ = NULL)
  74.     ;
  75.  
  76.   tab->patch_list = NULL;
  77.   local_patch_list_ptr = &tab->patch_list;
  78.   tab->next = local_table_list;
  79.   local_table_list = tab;
  80.   local_level++;
  81. }
  82.  
  83. /*
  84.  * Remove a local symbol table.
  85.  * The caller should check that local_level > 0 before calling this
  86.  */
  87. void remove_local_symtab(void)
  88. {
  89.   int i;
  90.   struct localtab *tab;
  91.   struct symbol *sym, *sym2;
  92.  
  93.   tab = local_table_list;
  94.  
  95.   for(i = 0; i < HASH_TABLE_SIZE; i++) {
  96.     for(sym = tab->table[i]; sym != NULL; sym = sym2) {
  97.       sym2 = sym->next;
  98.       mem_free(sym);
  99.     }
  100.   }
  101.  
  102.   local_table_list = tab->next;
  103.   if(local_table_list != NULL)
  104.     local_patch_list_ptr = &local_table_list->patch_list;
  105.  
  106.   mem_free(tab);
  107.   local_level--;
  108. }
  109.  
  110. /*
  111.  * Add a new symbol to the symbol table
  112.  */
  113. struct symbol *
  114. add_symbol(char *name, int tab)
  115. {
  116.   struct symbol *sym;
  117.   symtable *table;
  118.   int i;
  119.  
  120.   table = (tab == SYMTAB_LOCAL ? &local_table_list->table :
  121.         &global_symbol_table);
  122.  
  123.   if((sym = mem_alloc(sizeof(struct symbol) + strlen(name))) == NULL)
  124.     return NULL;
  125.  
  126.   i = hash(name);
  127.   sym->next = (*table)[i];
  128.   (*table)[i] = sym;
  129.  
  130.   strcpy(sym->name, name);
  131.  
  132. /* the caller must fill the value, type and flags fields */
  133.  
  134.   return sym;
  135. }
  136.  
  137. /*
  138.  * Try to find a symbol from the symbol table
  139.  */
  140. struct symbol *
  141. lookup_symbol(char *name, int tab)
  142. {
  143.   symtable *table;
  144.   struct symbol *sym;
  145.   int i;
  146.  
  147.   table = (tab == SYMTAB_LOCAL ? &local_table_list->table :
  148.         &global_symbol_table);
  149.  
  150.   i = hash(name);
  151.  
  152.   for(sym = (*table)[i]; sym != NULL; sym = sym->next) {
  153.     if(strcmp(sym->name, name) == 0)
  154.       return sym;
  155.   }
  156.  
  157.   return NULL;
  158. }
  159.  
  160. /*
  161.  * symbol table output for listing (global symbols only)
  162.  */
  163. void dump_symtab(FILE *fp)
  164. {
  165.   int i;
  166.   struct symbol *sym, *nsym, *s0, *s1;
  167.   struct symbol *syms = NULL;
  168.   
  169.   for(i = 0; i < HASH_TABLE_SIZE; i++) {
  170.     for(sym = global_symbol_table[i]; sym != NULL; sym = nsym) {
  171.       nsym = sym->next;
  172.       
  173.       for(s0 = NULL, s1 = syms; s1 != NULL; s0 = s1, s1 = s1->next) {
  174.         if(strcmp(s1->name, sym->name) > 0)
  175.           break;
  176.       }
  177.       
  178.       if(s0 == NULL) {
  179.         sym->next = syms;
  180.         syms = sym;
  181.       } else {
  182.         sym->next = s0->next;
  183.         s0->next = sym;
  184.       }
  185.     }
  186.   }
  187.  
  188.   fputs("\n\nSymbol Table:\nname                 decimal    hex\n", fp);
  189.  
  190.   for(sym = syms; sym != NULL; sym = sym->next) {
  191.       if(sym->type == SYM_MACRO)
  192.         fprintf(fp, "%-20s   MACRO\n", sym->name);
  193.       else if(sym->type == SYM_FORWARD)
  194.         fprintf(fp, "%-20s  UNDEFINED\n", sym->name);
  195.       else if(sym->type == SYM_DEFINED)
  196.         fprintf(fp, "%-20s  %6ld  0x%04lx\n",
  197.           sym->name, sym->v.value, sym->v.value);
  198.       else
  199.         fprintf(fp, "%-20s   ???\n", sym->name);
  200.   }
  201. }
  202.